#include "mcp23009.h"

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 

void mcp23009::init(uint8_t addr)
{
  _addr = addr;
  reset();
}

void mcp23009::reset()
{
  _mode = 0xff;
  _pullup = 0x00;
  _value = 0x00;
  send_data(MODE_REG, _mode);
  send_data(PULLUP_REG, _pullup);
  send_data(VALUE_REG, _value);
}  

void mcp23009::set_mode(uint8_t port, uint8_t val)
{
  bitWrite(_mode, port, val);
  send_data(MODE_REG, _mode);
}
  
void mcp23009::set_pullup(uint8_t port, uint8_t val)
{
  bitWrite(_pullup, port, val);
  send_data(PULLUP_REG, _pullup);
}

void mcp23009::set_value(uint8_t port, uint8_t val)
{
  bitWrite(_value, port, val);
  send_data(VALUE_REG, _value);
}


uint8_t mcp23009::get_value(uint8_t port)
{
  return(0x00); // NOT YET IMPLEMENTED
}

void mcp23009::send_data(uint8_t reg, uint8_t val)
{
  Wire.beginTransmission(_addr);
  Wire.send(reg);  
  Wire.send(val);  
  Wire.endTransmission();
}
